/**
 * 
 */
package org.braketester.model.containering;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;


/**
 * @author LAP
 *
 */
public class Containering implements Serializable {
	private static final long serialVersionUID = 438016461661121086L;
	private ArrayList<MassItem> massItems;
	private Double containerMass;
	private boolean massItemsInNeutons;
	private Date date;
	
	/**
	 * @return the date of creation
	 */
	public Date getDate() {
		return date;
	}

	/**
	 * @return the massItemsInNeutons
	 */
	public boolean isMassItemsInNeutons() {
		return massItemsInNeutons;
	}

	/**
	 * @param massItemsInNeutons the massItemsInNeutons to set
	 */
	public void setMassItemsInNeutons(boolean massItemsInNeutons) {
		this.massItemsInNeutons = massItemsInNeutons;
	}

	public Containering(Double containerMass) {
		setContainerMass(containerMass);
		massItems = new ArrayList<MassItem>();
		massItemsInNeutons = false;
		date = new Date();
	}
	
	public Double getContainerMass() {
		return containerMass;
	}
	
	public void setContainerMass(Double containerMass) throws IllegalArgumentException {
		if (containerMass < 0) throw new IllegalArgumentException("container mass must be zero or positive"); 
		this.containerMass = containerMass;
	}
	
	public void addItem(MassItem massItem) throws IllegalArgumentException {
		if (massItem.isMassInNeutons() != massItemsInNeutons) throw new IllegalArgumentException("Cant add this item " + massItem.toString());
		massItems.add(massItem);
		Collections.sort(massItems, new MassItemsComparator());
	}
	
	public MassItem getItemByIndex(int index) {
		return massItems.get(index);
	}
	
	public Double convertVoltageByContainering(Double voltage) {
		voltage -= getContainerMass();
		MassItem item = new MassItem(voltage, 1.0);
		item = selectNearest(item);
		return item.getDelta() * voltage;
	}
	
	private MassItem selectNearest(MassItem item) {
		int index = Collections.binarySearch(massItems, item, new MassItemsComparator());
		MassItem massItem = null;
		if (index == massItems.size()) massItem = massItems.get(index - 1);
		else {
			Double voltageDelta1 = item.getVoltage() - massItems.get(index).getVoltage();
			Double voltageDelta2 = massItems.get(index).getVoltage() - item.getVoltage();
			if (voltageDelta1 > voltageDelta2) massItem = massItems.get(index + 1);
			else massItem = massItems.get(index);
		}
		return massItem;
	}
	
	private class MassItemsComparator implements Comparator<MassItem> {
		@Override
		public int compare(MassItem o1, MassItem o2) {
			int ret = 0;
			if (o1.getVoltage() > o2.getVoltage()) ret = 1;
			else if(o1.getVoltage() < o2.getVoltage()) ret =-1;
			return ret;
		}
	}
}
